<template>
  <div
    class="absolute adaptimg"
    :style="{ width: width ? width + 'px' : 'auto', height: height ? height + 'px' : 'auto' }"
  >
    <img
      ref="imgEl"
      class="block"
      :src="innerSrc"
      :style="{ width: width ? width + 'px' : 'auto', height: height ? height + 'px' : 'auto' }"
      @load="onload"
      @error="onerror"
    />
    <slot />
  </div>
</template>
<script setup lang="ts">
import { onBeforeUnmount, onMounted, ref } from "vue";
import ResizeObserver from "resize-observer-polyfill";

const props = withDefaults(
  defineProps<{
    src: string;
    defaultSrc?: string;
  }>(),
  {
    defaultSrc: "/project_cover.png",
  }
);

const innerSrc = ref(props.src);
const width = ref(0);
const height = ref(0);
const imgEl = ref<HTMLImageElement>();
let whFactor = 0;

function onload() {
  if (imgEl.value) {
    whFactor = imgEl.value.width / imgEl.value.height;
    const containerEl = imgEl.value.parentNode?.parentNode as HTMLElement;
    if (containerEl) {
      const containerW = containerEl.offsetWidth;
      const containerH = containerEl.offsetHeight;
      resize(containerW, containerH);
    }
  }
}

function onerror() {
  if (innerSrc.value !== props.defaultSrc) {
    innerSrc.value = props.defaultSrc;
  }
}

function resize(containerW, containerH) {
  if (!whFactor) return;
  const newH = containerW / whFactor;
  if (newH > containerH) {
    width.value = containerH * whFactor;
    height.value = containerH;
  } else {
    width.value = containerW;
    height.value = newH;
  }
}

let resizeObserver: ResizeObserver | null;
onMounted(() => {
  if (imgEl.value) {
    const containerEl = imgEl.value.parentNode?.parentNode as HTMLElement;
    resizeObserver = new ResizeObserver((entries: ResizeObserverEntry[]) => {
      const entry = entries[0];
      if (entry) {
        resize(entry.contentRect.width, entry.contentRect.height);
      }
    });
    resizeObserver.observe(containerEl);
  }
});
onBeforeUnmount(() => {
  if (resizeObserver) {
    resizeObserver.disconnect();
    resizeObserver = null;
  }
});
</script>
<style>
.adaptimg {
  left: 50%;
  top: 50%;
  transform: translate3d(-50%, -50%, 0);
  -webkit-transform: translate3d(-50%, -50%, 0);
}
</style>
